package com.navinfo.platform.trip.common.arithmetic;

import com.navinfo.platform.trip.common.arithmetic.data.CommonData;
import com.navinfo.platform.trip.common.arithmetic.data.OuterStatisticData;
import com.navinfo.platform.trip.common.arithmetic.enums.WorkingConditionEnum;
import com.navinfo.platform.trip.common.arithmetic.manager.AbstractArithmetic;
import com.navinfo.platform.trip.common.arithmetic.var.VarWorkingCondition;
import com.navinfo.platform.trip.common.arithmetic.var.VarWorkingCondition.CacheCondition;
import com.navinfo.platform.trip.common.arithmetic.var.VarWorkingCondition.CachePoint;
import com.navinfo.platform.trip.common.config.ConfigMap;
import com.navinfo.platform.trip.common.util.ArithmeticUtils;
import com.navinfo.platform.trip.common.util.BigDecimalUtils;
import org.apache.flink.shaded.guava18.com.google.common.collect.EvictingQueue;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import static com.navinfo.platform.trip.common.arithmetic.enums.WorkingConditionEnum.*;
import static com.navinfo.platform.trip.common.arithmetic.var.VarWorkingCondition.*;
import static java.math.BigDecimal.ROUND_HALF_UP;

/**
 * 东风新版——工况统计
 * @author:  web
 * @date: 2020-07-06
 **/
public class WorkingCondition_DFN extends AbstractArithmetic<VarWorkingCondition> {
    /**
     * 后期需要从前端读取
     * 加速工况，加速度阀值，单位m/s2
     */
    private Float accelerateThreshold = ConfigMap.getFloat("DFN_WorkingCondition_Accelerate_Threshold");
    /**
     * 后期需要从前端读取
     * 减速工况，加速度阀值，单位m/s2
     */
    private Float decelerateThreshold = ConfigMap.getFloat("DFN_WorkingCondition_Decelerate_Threshold");

    @Override
    public void calculate() {
        logger.debug("===============东风工况算法开始===========");

        //1、将位置点放入具体的工况缓存数据列表
        getObj().setPreStatus(isIdleCondition() ? IDLE : otherCondition());

        //2、如果最后一个点，清空位置点缓存定长队列中的数据
        if(getCommonData().isTripLastNode()){
            clearCachePoints();
        }

        logger.debug("===============东风工况算法结束===========");
    }

    @Override
    public void collect(OuterStatisticData out) {
        //怠速工况异常点处理
        handleIdleConditions();

        //怠速工况结果处理
        ConditionResult idleResult = collectCondition(IDLE);
        out.setIdleConditionDuration(idleResult.getDuration());
        out.setIdleConditionFuel(ArithmeticUtils.fuelMlToMl(idleResult.getFuel()));

        //低速工况结果处理
        ConditionResult lowResult = collectCondition(LOW);
        out.setLowConditionDuration(lowResult.getDuration());
        out.setLowConditionFuel(ArithmeticUtils.fuelMlToMl(lowResult.getFuel()));
        out.setLowConditionSpeedAvg(lowResult.getSpeedAvg());
        out.setLowConditionSpeedStDev(lowResult.getSpeedStDev());
        out.setLowConditionAccelerationAvg(lowResult.getAccelerationAvg());
        out.setLowConditionAccelerationStDev(lowResult.getAccelerationStDev());
        out.setLowConditionRpmAvg(lowResult.getRpmAvg());
        out.setLowConditionRpmStDev(lowResult.getRpmStDev());
        out.setLowConditionThrottleAvg(lowResult.getThrottleAvg());
        out.setLowConditionThrottleStDev(lowResult.getThrottleStDev());
        out.setLowConditionThrottleRateAvg(lowResult.getThrottleRateAvg());
        out.setLowConditionThrottleRateStDev(lowResult.getThrottleRateStDev());

        //加速工况结果处理
        ConditionResult accResult = collectCondition(ACCELERATE);
        out.setAccelerateConditionDuration(accResult.getDuration());
        out.setAccelerateConditionFuel(ArithmeticUtils.fuelMlToMl(accResult.getFuel()));
        out.setAccelerateConditionSpeedAvg(accResult.getSpeedAvg());
        out.setAccelerateConditionSpeedStDev(accResult.getSpeedStDev());
        out.setAccelerateConditionAccelerationAvg(accResult.getAccelerationAvg());
        out.setAccelerateConditionAccelerationStDev(accResult.getAccelerationStDev());
        out.setAccelerateConditionRpmAvg(accResult.getRpmAvg());
        out.setAccelerateConditionRpmStDev(accResult.getRpmStDev());
        out.setAccelerateConditionThrottleAvg(accResult.getThrottleAvg());
        out.setAccelerateConditionThrottleStDev(accResult.getThrottleStDev());
        out.setAccelerateConditionThrottleRateAvg(accResult.getThrottleRateAvg());
        out.setAccelerateConditionThrottleRateStDev(accResult.getThrottleRateStDev());

        //减速工况结果处理
        ConditionResult decResult = collectCondition(DECELERATE);
        out.setDecelerateConditionDuration(decResult.getDuration());
        out.setDecelerateConditionFuel(ArithmeticUtils.fuelMlToMl(decResult.getFuel()));
        out.setDecelerateConditionSpeedAvg(decResult.getSpeedAvg());
        out.setDecelerateConditionSpeedStDev(decResult.getSpeedStDev());
        out.setDecelerateConditionAccelerationAvg(decResult.getAccelerationAvg());
        out.setDecelerateConditionAccelerationStDev(decResult.getAccelerationStDev());

        //匀速工况结果处理
        ConditionResult uniformResult = collectCondition(UNIFORM);
        out.setUniformConditionDuration(uniformResult.getDuration());
        out.setUniformConditionFuel(ArithmeticUtils.fuelMlToMl(uniformResult.getFuel()));
        out.setUniformConditionSpeedAvg(uniformResult.getSpeedAvg());
        out.setUniformConditionSpeedStDev(uniformResult.getSpeedStDev());
        out.setUniformConditionAccelerationAvg(uniformResult.getAccelerationAvg());
        out.setUniformConditionAccelerationStDev(uniformResult.getAccelerationStDev());
        out.setUniformConditionRpmAvg(uniformResult.getRpmAvg());
        out.setUniformConditionRpmStDev(uniformResult.getRpmStDev());
        out.setUniformConditionThrottleAvg(uniformResult.getThrottleAvg());
        out.setUniformConditionThrottleStDev(uniformResult.getThrottleStDev());
        out.setUniformConditionThrottleRateAvg(uniformResult.getThrottleRateAvg());
        out.setUniformConditionThrottleRateStDev(uniformResult.getThrottleRateStDev());
    }

    /**
     * 怠速工况异常点处理<br/>
     * 连续大于3个速度>0的点划入低速工况<br/>
     * 剩下的点划分为不同的工况段<br/>
     */
    private void handleIdleConditions() {
        VarWorkingCondition obj = getObj();

        List<CacheCondition> idleConditions = new ArrayList<>();
        obj.getIdleConditions().forEach(condition -> {
            //上个点是异常点
            boolean preError = false;
            //缓存的正确位置点集合
            List<CachePoint> exactPoints = new ArrayList<>();
            //缓存的异常位置点集合
            List<CachePoint> errorPoints = new ArrayList<>();
            for(CachePoint point : condition.getPoints()){
                //当前点是异常点
                if(point.getNewSpeed() > 0){
                    errorPoints.add(point);
                    preError = true;
                    continue;
                }

                //当前点是正常点
                if(preError){
                    if(errorPoints.size() > 3){
                        //异常点放入低速工况
                        obj.getLowConditions().add(newCondition(errorPoints));
                        errorPoints.clear();

                        //正常点放入怠速工况
                        idleConditions.add(newCondition(exactPoints));
                        exactPoints.clear();
                    }else{
                        //异常点放入正常点集合
                        exactPoints.addAll(errorPoints);
                        errorPoints.clear();
                    }
                }

                exactPoints.add(point);
                preError = false;
            }

            //处理没被处理的缓存集合
            if(errorPoints.size() > 3) {
                //异常点放入低速工况
                obj.getLowConditions().add(newCondition(errorPoints));
            } else {
                //异常点放入正常点集合
                exactPoints.addAll(errorPoints);
            }

            //正常点放入怠速工况
            if(exactPoints.size()>0){
                idleConditions.add(newCondition(exactPoints));
            }
            errorPoints.clear();
            exactPoints.clear();
        });

        //处理后的正确结果放入怠速工况缓存数据列表中
        obj.setIdleConditions(idleConditions);
    }

    /**
     * 1、怠速工况处理<br/>
     *      a，发动机转速>0<br/>
     *      b，油门开度=0；<br/>
     *      c，车速=0，但偶尔出现车速<=2KM/H的数值时，视为异常，仍按0处理。<br/>
     *          如果在速度过程中连续三个点小于等于2后又回归到速度0,认为是怠速<br/>
     *  @return 工况状态
     */
    private boolean isIdleCondition() {
        CommonData commonData = getCommonData();
        if(commonData.getRotation()>0 && commonData.getAcceleratorPosition()==0 && commonData.getSpeedKmh()>=0 && commonData.getSpeedKmh()<=2){
            VarWorkingCondition obj = getObj();
            List<CacheCondition> idleConditions = obj.getIdleConditions();
            CachePoint cachePoint = convertCachePoint(commonData);

            //1、上一点不是怠速工况
            if(! IDLE.equals(obj.getPreStatus()) ) {
                //1.1、开启新的工况缓存数据，并加入当前点
                idleConditions.add(newCondition(cachePoint));
            }

            //1.2、上一点是怠速工况
            else{
                int size = idleConditions.size();
                //1.2.1、正常情况，当前点加入最新的工况缓存
                if(size > 0){
                    idleConditions.get(size-1).addPoint(cachePoint);
                }
                //1.2.2、异常情况，新开启工况缓存，并加入当前点
                else{
                    idleConditions.add(newCondition(cachePoint));
                }
            }

            //1.1.3、清空其他工况的缓存队列
            clearCachePoints();
            return true;
        }

        return false;
    }

    /**
     * 2、其他工况需要对速度进行处理，将车速按照前1个点及后1个点累加再除3, 处理后的车速保留小数点后一位<br/>
     * 上报的车速为    22、24、25、26、28<br/>
     *   则22处理后为   （22+24）/2<br/>
     *   则24处理后为   （22+24+25）/3<br/>
     *   则25处理后为   （24+25+26）/3<br/>
     *   则26处理后为   （25+26+28）/3<br/>
     *   则28处理后为   （26+28）/2<br/>
     */
    private WorkingConditionEnum otherCondition() {
        VarWorkingCondition obj = getObj();
        WorkingConditionEnum preStatus = obj.getPreStatus();
        EvictingQueue<CachePoint> cachePoints = obj.getCachePoints();
        CommonData commonData = getCommonData();

        //2.1、将当前点加入到工况缓存队列
        cachePoints.add(convertCachePoint(commonData));

        //2.2、如果队列个数==1，不做其他处理，继续缓存
        int size = cachePoints.size();
        if(size == 1){
            return CACHING;
        }

        //2.3、如果队列数==2
        if(size == 2){
            //2.3.1、通过前两个点的平均值，更新第一个点的速度；
            CachePoint[] pointArr = cachePoints.toArray(new CachePoint[0]);
            CachePoint firstPoint = pointArr[0];

            BigDecimal speedAvgMS = BigDecimalUtils.divide(Optional.ofNullable(firstPoint.getOldSpeed()).orElse(BigDecimal.ZERO)
                    .add(Optional.ofNullable(pointArr[1].getOldSpeed()).orElse(BigDecimal.ZERO)), 2, 2);
            firstPoint.setNewSpeed(speedAvgMS.multiply(new BigDecimal("3.6")).setScale(1, ROUND_HALF_UP).floatValue());

            //2.3.2、获取当前点的工况状态
            WorkingConditionEnum pointStatus = pointStatus(firstPoint, null);

            //2.3.3、开启新的工况缓存数据
            Optional.ofNullable(getConditionList(pointStatus)).ifPresent(list -> list.add(newCondition(firstPoint)));

            return pointStatus;
        }

        //2.4、如果位置点缓存个数==3
        if(size == 3) {
            //2.3.1、通过三个点的平均值，更新第二个点的速度；
            CachePoint[] pointArr = cachePoints.toArray(new CachePoint[0]);
            CachePoint firstPoint = pointArr[0];
            CachePoint secondPoint = pointArr[1];
            BigDecimal speedAvgMS = BigDecimalUtils.divide(Optional.ofNullable(firstPoint.getOldSpeed()).orElse(BigDecimal.ZERO)
                    .add(Optional.ofNullable(secondPoint.getOldSpeed()).orElse(BigDecimal.ZERO))
                    .add(Optional.ofNullable(pointArr[2].getOldSpeed()).orElse(BigDecimal.ZERO)), 3, 2);

            secondPoint.setLastGpsTime(firstPoint.getGpsTime());
            secondPoint.setLastOldSpeed(firstPoint.getOldSpeed());
            secondPoint.setLastNewSpeed(firstPoint.getNewSpeed());
            secondPoint.setNewSpeed(speedAvgMS.multiply(new BigDecimal("3.6")).setScale(1, ROUND_HALF_UP).floatValue());

            //2.3.2、获取上一点的工况缓存数据
            List<CacheCondition> conditionList = getConditionList(preStatus);
            int conditionSize = null==conditionList ? 0 :conditionList.size();
            CacheCondition preCondition = conditionSize>0 ? conditionList.get(conditionSize-1) : null;

            //2.3.3、获取当前点工况状态
            WorkingConditionEnum pointStatus = pointStatus(secondPoint, preCondition);

            //2.3.4、如果上一点工况缓存数据不为空 并且 上一点工况状态和第二工况状态一致
            if(null!=preCondition && pointStatus.equals(preStatus)){
                preCondition.addPoint(secondPoint);
            }
            //2.3.5、否则，开启新的工况缓存数据
            else{
                Optional.ofNullable(getConditionList(pointStatus)).ifPresent(list -> list.add(newCondition(secondPoint)));
            }

            return  pointStatus;
        }

        return CACHING;
    }

    /**
     * 通过CommonData转换成其他工况的位置点
     * @param commonData 公共数据
     * @return 缓存点
     */
    private CachePoint convertCachePoint(CommonData commonData){
        CachePoint cachePoint = new CachePoint();
        cachePoint.setGpsTime(commonData.getGpsTime());
        cachePoint.setLastGpsTime(commonData.getLastGpsTime());
        cachePoint.setOldSpeed(commonData.getSpeedMs());
        cachePoint.setLastOldSpeed(commonData.getLastSpeedMs());
        cachePoint.setNewSpeed(commonData.getSpeedKmh());
        BigDecimal lastSpeedMS = Optional.ofNullable(commonData.getLastSpeedMs()).orElse(BigDecimal.ZERO);
        cachePoint.setLastNewSpeed(lastSpeedMS.multiply(new BigDecimal("3.6")).setScale(1, ROUND_HALF_UP).floatValue());
        cachePoint.setRotation(commonData.getRotation());
        cachePoint.setFuelConsumptionRate(commonData.getFuelConsumptionRate());
        cachePoint.setThrottlePosition((int) commonData.getAcceleratorPosition());
        return cachePoint;
    }

    /**
     * 开启新的工况缓存数据
     * @param point 缓存位置点
     * @return 工况缓存数据
     */
    private CacheCondition newCondition(CachePoint point){
        CacheCondition condition = new CacheCondition();
        if(null != point){
            condition.setStartTime(point.getGpsTime());
            condition.setStartSpeed(point.getNewSpeed());
            condition.addPoint(point);
        }
        return condition;
    }

    /**
     * 开启新的工况缓存数据
     * @param points 缓存位置点集合
     * @return 工况缓存数据
     */
    private CacheCondition newCondition(List<CachePoint> points){
        CacheCondition condition = new CacheCondition();
        if(null!=points && points.size()>0){
            CachePoint firstPoint = points.get(0);
            condition.setStartTime(firstPoint.getGpsTime());
            condition.setStartSpeed(firstPoint.getNewSpeed());
            condition.addAllPoints(points);
        }

        return condition;
    }

    /**
     * 获取工况对应的工况缓存数据列表
     * @param conditionEnum 工况状态
     * @return 缓存数据列表
     */
    private List<CacheCondition> getConditionList(WorkingConditionEnum conditionEnum){
        VarWorkingCondition obj = getObj();
        List<CacheCondition> cacheConditions = null;
        switch (conditionEnum){
            case IDLE:
                cacheConditions = obj.getIdleConditions();
                break;
            case LOW:
                cacheConditions = obj.getLowConditions();
                break;
            case ACCELERATE:
                cacheConditions = obj.getAccConditions();
                break;
            case DECELERATE:
                cacheConditions = obj.getDecConditions();
                break;
            case UNIFORM:
                cacheConditions = obj.getUniformConditions();
                break;
        }

        return cacheConditions;
    }

    /**
     * 根据位置点计算除怠速工况外的其他工况
     * @param point 其他工况缓存位置点
     * @param preCondition 上个点工况的缓存数据
     * @return 工况状态
     */
    private WorkingConditionEnum pointStatus(CachePoint point, CacheCondition preCondition){
        float curSpeed = point.getNewSpeed();
        /*【匀速工况】
         *  1，车速大于0小于20  公里/小时。
         */
        if(curSpeed>0 && curSpeed<=20){
            return LOW;
        }

        //计算加速度
        long lastTime = point.getLastGpsTime();
        float lastSpeed = point.getLastNewSpeed();
        if(null != preCondition){
            lastTime = preCondition.getStartTime();
            lastSpeed = preCondition.getStartSpeed();
        }
        BigDecimal dffSpeedMS = BigDecimalUtils.divide((double) (curSpeed - lastSpeed), 3.6, 2);
        BigDecimal dffTimeS = BigDecimalUtils.divide(point.getGpsTime() - lastTime, 1000, 2);
        float acceleration = BigDecimalUtils.divide(dffSpeedMS.doubleValue(), dffTimeS.doubleValue(), 2).floatValue();

        /*【加速工况】
         *  1，发动机转速大于0
         *  2，车速>20 公里/小时；
         *  3，加速度>0.7m/ 𝑠2。从加速初始点到加速截止点的整体加速度
         *  4，速度不断增加
         */
        if(point.getRotation()>0 && curSpeed>20 && curSpeed>point.getLastNewSpeed() && acceleration>accelerateThreshold){
            return ACCELERATE;
        }

        /*【减速工况】
         *  1，发动机转速大于0
         *  2，车速>20 公里/小时；
         *  3，加速度< - 0.7m/ 𝑠2。从减速初始点到减速截止点的整体加速度
         *  4，速度不断减少
         */
        if(point.getRotation()>0 && curSpeed>20 && curSpeed<point.getLastNewSpeed() && acceleration<decelerateThreshold){
            return DECELERATE;
        }

        /*【匀速工况】：
         *  处理后的数据去掉低速、加速、减速工况，剩下的就是匀速工况
         */
        return UNIFORM;
    }

    /**
     * 清空 其他工况的定长缓存队列 <br/>
     *    如果队列长度为1，不能计算第一个点的速度，丢弃<br/>
     *    如果队列长度为2，第一个点速度已更新并进行了工况判断，第二个点不能计算出速度，丢弃<br/>
     *    如果队列长度为3，前两个点的速度都已更新并进行了状态判断，故计算最后一个点的速度，并进行工况判断<br/>
     */
    private void clearCachePoints() {
        VarWorkingCondition obj = getObj();
        EvictingQueue<CachePoint> cachePoints = obj.getCachePoints();

        if(3 == cachePoints.size()){
            CachePoint[] pointArray = cachePoints.toArray(new CachePoint[0]);
            //使用最后两个点计算最后一个点的速度
            CachePoint secondPoint = pointArray[1];
            CachePoint thirdPoint = pointArray[2];
            BigDecimal secondSpeed = Optional.ofNullable(secondPoint.getOldSpeed()).orElse(BigDecimal.ZERO);
            BigDecimal thirdSpeed = Optional.ofNullable(thirdPoint.getOldSpeed()).orElse(BigDecimal.ZERO);
            float avgSpeed = BigDecimalUtils.divide(secondSpeed.add(thirdSpeed), 2,2).multiply(BigDecimal.valueOf(3.6)).setScale(1,ROUND_HALF_UP).floatValue();

            thirdPoint.setNewSpeed(avgSpeed);
            thirdPoint.setLastOldSpeed(secondSpeed);
            thirdPoint.setLastGpsTime(secondPoint.getGpsTime());
            thirdPoint.setLastNewSpeed(secondPoint.getNewSpeed());

            //如果上个点对应的工况缓存数据列表有值，判断是否放入上个工况
            //如果上个点对应的工况缓存数据列表无值，一个点直接丢弃
            WorkingConditionEnum preStatus = obj.getPreStatus();
            Optional.ofNullable(getConditionList(preStatus)).ifPresent(list -> {
                int size = list.size();
                //如果上个点对应的工况缓存数据有值
                if(size > 0){
                    CacheCondition preCondition = list.get(size - 1);
                    List<CachePoint> points = preCondition.getPoints();
                    //前一个点的工况和第三个点的工况一致，则将第三个点放入该工况缓存
                    if(points.size()>0 && preStatus.equals(pointStatus(thirdPoint, preCondition))){
                        points.add(thirdPoint);
                    }
                }
            });
        }

        cachePoints.clear();
    }

    /**
     * 收集工况的统计数据
     * @param conditionEnum 工况状态
     */
    private ConditionResult collectCondition(WorkingConditionEnum conditionEnum){
        ConditionResult conditionResult = new ConditionResult();

        List<CacheCondition> conditions = getConditionList(conditionEnum);
        if(null!=conditions && conditions.size()>0){
            List<Float> speedList = new ArrayList<>();
            List<Float> accelerationList = new ArrayList<>();
            List<Integer> rpmList = new ArrayList<>();
            List<Integer> throttleList = new ArrayList<>();
            List<Integer> throttleRateList = new ArrayList<>();

            //工况每段加速度、油门变化率总和，先求每段平均值，再整体求平均值
            double accelerationAvgSum = 0.0;
            double throttleRateAvgSum = 0.0;
            for(CacheCondition condition : conditions){
                List<CachePoint> points = condition.getPoints();
                double accelerationSum = 0.0;
                int accelerationCount = 0;
                int throttleRateSum = 0;
                int throttleRateCount = 0;
                CachePoint prePoint = null;
                for (CachePoint point : points) {
                    //累加时长，单位s
                    //第一个点的上一个gps时间赋值为当前点时间
                    long lastGpsTime = point.getLastGpsTime()==0 ? point.getGpsTime() : point.getLastGpsTime();
                    BigDecimal dffTimeS = BigDecimalUtils.divide(point.getGpsTime() - lastGpsTime, 1000, 2);
                    conditionResult.addDuration(dffTimeS.intValue());

                    //累加油耗，单位ml，发动机燃油消耗率(单位:L/H)转换成ml/s
                    BigDecimal fuelConsumptionRate = point.getFuelConsumptionRate().divide(BigDecimal.valueOf(3.6), 2, ROUND_HALF_UP);
                    conditionResult.addFuel(fuelConsumptionRate.multiply(dffTimeS).setScale(2, ROUND_HALF_UP).doubleValue());

                    //怠速工况不统计速度、加速度、转速、油门开度、油门开度变化率；
                    if (! IDLE.equals(conditionEnum)) {
                        //添加速度
                        float newSpeed = point.getNewSpeed();
                        speedList.add(newSpeed);

                        //添加加速度
                        if (!BigDecimal.ZERO.equals(dffTimeS)) {
                            BigDecimal dffSpeedMS = BigDecimalUtils.divide((double) (newSpeed - point.getLastNewSpeed()), 3.6, 2);
                            float acceleration = BigDecimalUtils.divide(dffSpeedMS.doubleValue(), dffTimeS.doubleValue(), 2).floatValue();
                            accelerationSum += acceleration;
                            ++accelerationCount;
                            accelerationList.add(acceleration);
                        }

                        //减速工况不统计转速、油门、油门变化率
                        if (! DECELERATE.equals(conditionEnum)) {
                            //添加发动机转速
                            rpmList.add(point.getRotation());

                            //添加油门开度
                            throttleList.add(point.getThrottlePosition());

                            //添加油门开度变化率
                            if (null != prePoint) {
                                int dffThrottle = point.getThrottlePosition() - prePoint.getThrottlePosition();
                                if (dffThrottle > 0) {
                                    throttleRateSum += dffThrottle;
                                    ++throttleRateCount;
                                    throttleRateList.add(dffThrottle);
                                }
                            }
                        }
                    }
                    //缓存上个点
                    prePoint = point;
                }

                //怠速工况不统计加速度
                if(! IDLE.equals(conditionEnum)){
                    //每个工况的对应的位置点大小
                    accelerationAvgSum += BigDecimalUtils.divide(accelerationSum, accelerationCount,2).doubleValue();

                    //减速工况不统计油门开度变化率；
                    if(!DECELERATE.equals(conditionEnum)){
                        throttleRateAvgSum += BigDecimalUtils.divide(throttleRateSum, throttleRateCount, 2).doubleValue();
                    }
                }
            }

            //怠速工况不统计速度、加速度、转速、油门开度、油门开度变化率；
            if(!IDLE.equals(conditionEnum)){
                //工况列表的大小
                int conditionSize = conditions.size();

                Float[] speedArr = speedList.toArray(new Float[0]);
                conditionResult.setSpeedAvg((int) (BigDecimalUtils.average(speedArr) * 100));
                conditionResult.setSpeedStDev((int) (BigDecimalUtils.standardDeviation(speedArr) * 100));

                Float[] accelerationArr = accelerationList.toArray(new Float[0]);
                conditionResult.setAccelerationStDev((int) (BigDecimalUtils.standardDeviation(accelerationArr) * 100));
                conditionResult.setAccelerationAvg((int) (BigDecimalUtils.divide(accelerationAvgSum, conditionSize,2).doubleValue() * 100));

                //减速工况不统计转速、油门开度、油门开度变化率；
                if(! DECELERATE.equals(conditionEnum)){
                    Integer[] rpmArr = rpmList.toArray(new Integer[0]);
                    conditionResult.setRpmAvg((int) (BigDecimalUtils.average(rpmArr) * 100));
                    conditionResult.setRpmStDev((int) (BigDecimalUtils.standardDeviation(rpmArr) * 100));

                    Integer[] throttleArr = throttleList.toArray(new Integer[0]);
                    conditionResult.setThrottleAvg((int) (BigDecimalUtils.average(throttleArr) * 100));
                    conditionResult.setThrottleStDev((int) (BigDecimalUtils.standardDeviation(throttleArr) * 100));

                    Integer[] throttleRageArr = throttleRateList.toArray(new Integer[0]);
                    conditionResult.setThrottleRateStDev((int) (BigDecimalUtils.standardDeviation(throttleRageArr) * 100));
                    conditionResult.setThrottleRateAvg((int) (BigDecimalUtils.divide(throttleRateAvgSum, conditionSize,2).doubleValue() * 100));
                }
            }
        }

        return conditionResult;
    }
}
